package ppmt;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.util.List;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.*;


//生成图表插件
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.awt.Graphics2D;

import java.awt.Color;
import java.awt.Font;

//生成更好的图表
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;

public class ToySalesSystem extends JFrame {
    // 数据库连接信息
    private static final String DB_URL = "jdbc:mysql://localhost:3306/sms（gui）?useSSL=false";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "huang8824863";

    // 当前登录用户信息
    private static String currentUser;
    private static String currentRole;

    // UI组件
    private JTabbedPane tabbedPane;

    // 各个模块面板
    private ProductPanel productPanel;
    private SalesPanel salesPanel;
    private SupplierPanel supplierPanel;
    private UserPanel userPanel;
    private SettlementPanel settlementPanel;
    private CategoryPanel categoryPanel;

    public ToySalesSystem() {
        super("潮玩商品售卖管理系统");
        setSize(1200, 800);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

        // 创建标签页
        tabbedPane = new JTabbedPane();

        // 初始化各个模块
        productPanel = new ProductPanel();
        salesPanel = new SalesPanel();
        supplierPanel = new SupplierPanel();
        userPanel = new UserPanel();
        settlementPanel = new SettlementPanel();
        categoryPanel = new CategoryPanel();

        // 添加标签页
        tabbedPane.addTab("商品管理", productPanel);
        tabbedPane.addTab("销售管理", salesPanel);
        tabbedPane.addTab("供应商管理", supplierPanel);
        tabbedPane.addTab("用户管理", userPanel);
        tabbedPane.addTab("结算服务", settlementPanel);
        tabbedPane.addTab("分类管理", categoryPanel);

        // 初始只显示登录界面
        tabbedPane.setVisible(false);

        // 添加登录面板
        LoginPanel loginPanel = new LoginPanel(this);
        getContentPane().add(loginPanel, BorderLayout.CENTER);
    }

    // 登录成功后显示主界面
    public void loginSuccess(String username, String role) {
        currentUser = username;
        currentRole = role;

        getContentPane().removeAll();
        getContentPane().add(tabbedPane, BorderLayout.CENTER);
        tabbedPane.setVisible(true);

        // 根据角色设置权限
        if ("user".equals(role)) {
            tabbedPane.setEnabledAt(3, false); // 禁用用户管理
        }

        revalidate();
        repaint();
    }

    // 主入口
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            new ToySalesSystem().setVisible(true);
        });
    }

    // 数据库连接工具类
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
    }

    // ========================== 登录面板 ==========================
    class LoginPanel extends JPanel {
        private JTextField usernameField;
        private JPasswordField passwordField;

        public LoginPanel(ToySalesSystem parent) {
            setLayout(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.insets = new Insets(10, 10, 10, 10);

            // 标题
            JLabel titleLabel = new JLabel("潮玩商品售卖管理系统");
            titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 24));
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.gridwidth = 2;
            add(titleLabel, gbc);

            // 用户名
            gbc.gridwidth = 1;
            gbc.gridy = 1;
            gbc.gridx = 0;
            add(new JLabel("用户名:"), gbc);

            gbc.gridx = 1;
            usernameField = new JTextField(20);
            add(usernameField, gbc);

            // 密码
            gbc.gridy = 2;
            gbc.gridx = 0;
            add(new JLabel("密码:"), gbc);

            gbc.gridx = 1;
            passwordField = new JPasswordField(20);
            add(passwordField, gbc);

            // 登录按钮
            gbc.gridy = 3;
            gbc.gridx = 0;
            gbc.gridwidth = 2;
            JButton loginButton = new JButton("登录");
            loginButton.addActionListener(e -> {
                String username = usernameField.getText();
                String password = new String(passwordField.getPassword());

                if (authenticateUser(username, password)) {
                    parent.loginSuccess(username, currentRole);
                } else {
                    JOptionPane.showMessageDialog(parent, "用户名或密码错误", "登录失败", JOptionPane.ERROR_MESSAGE);
                }
            });
            add(loginButton, gbc);
        }

        private boolean authenticateUser(String username, String password) {
            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "SELECT * FROM tb_user WHERE username = ? AND password = ?")) {

                stmt.setString(1, username);
                stmt.setString(2, password);

                ResultSet rs = stmt.executeQuery();
                if (rs.next()) {
                    currentRole = rs.getString("role");
                    return true;
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            return false;
        }
    }

    // ========================== 结算服务面板 ==========================
    class SettlementPanel extends JPanel {
        private JTable cartTable;
        private DefaultTableModel tableModel;
        private JTextField productIdField, quantityField;
        private JLabel totalLabel;

        public SettlementPanel() {
            setLayout(new BorderLayout());

            // 顶部输入面板
            JPanel inputPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
            inputPanel.add(new JLabel("商品ID:"));
            productIdField = new JTextField(10);
            inputPanel.add(productIdField);

            inputPanel.add(new JLabel("数量:"));
            quantityField = new JTextField(5);
            inputPanel.add(quantityField);

            JButton addButton = new JButton("添加商品");
            addButton.addActionListener(e -> addToCart());
            inputPanel.add(addButton);

            JButton settleButton = new JButton("结算");
            settleButton.addActionListener(e -> settleTransaction());
            inputPanel.add(settleButton);

            JButton clearButton = new JButton("清空购物车");
            clearButton.addActionListener(e -> clearCart());
            inputPanel.add(clearButton);

            totalLabel = new JLabel("总计: 0.00元");
            inputPanel.add(totalLabel);

            add(inputPanel, BorderLayout.NORTH);

            // 购物车表格
            String[] columnNames = {"商品ID", "商品名称", "单价", "数量", "小计"};
            tableModel = new DefaultTableModel(columnNames, 0);
            cartTable = new JTable(tableModel);
            JScrollPane scrollPane = new JScrollPane(cartTable);
            add(scrollPane, BorderLayout.CENTER);
        }

        private void addToCart() {
            try {
                int productId = Integer.parseInt(productIdField.getText());
                int quantity = Integer.parseInt(quantityField.getText());

                if (quantity <= 0) {
                    JOptionPane.showMessageDialog(this, "数量必须大于0", "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }

                // 修改查询语句，关联tb_group表
                try (Connection conn = getConnection();
                     PreparedStatement stmt = conn.prepareStatement(
                             "SELECT p.id, p.product_name, p.sale_price, g.id as group_id " +
                                     "FROM tb_product p " +
                                     "LEFT JOIN tb_group g ON p.group_id = g.id " +
                                     "WHERE p.id = ?")) {

                    stmt.setInt(1, productId);
                    ResultSet rs = stmt.executeQuery();

                    if (rs.next()) {
                        String name = rs.getString("product_name");
                        // 处理空值情况
                        if (name == null || name.trim().isEmpty()) {
                            name = "未知商品";
                        }
                        float price = rs.getFloat("sale_price");
                        float subtotal = price * quantity;

                        // 添加到表格
                        Object[] row = {productId, name, price, quantity, subtotal};
                        tableModel.addRow(row);

                        // 更新总计
                        updateTotal();
                    } else {
                        JOptionPane.showMessageDialog(this, "商品不存在", "错误", JOptionPane.ERROR_MESSAGE);
                    }
                }
            } catch (NumberFormatException ex) {
                JOptionPane.showMessageDialog(this, "请输入有效的数字", "错误", JOptionPane.ERROR_MESSAGE);
            } catch (SQLException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(this, "数据库错误: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }

        private void updateTotal() {
            float total = 0;
            for (int i = 0; i < tableModel.getRowCount(); i++) {
                total += (float) tableModel.getValueAt(i, 4);
            }
            totalLabel.setText("总计: " + String.format("%.2f", total) + "元");
        }

        private void settleTransaction() {
            if (tableModel.getRowCount() == 0) {
                JOptionPane.showMessageDialog(this, "购物车为空", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            // 先检查所有商品库存是否足够
            try (Connection conn = getConnection()) {
                conn.setAutoCommit(false); // 开始事务

                // 检查库存阶段
                for (int i = 0; i < tableModel.getRowCount(); i++) {
                    int productId = (int) tableModel.getValueAt(i, 0);
                    int quantity = (int) tableModel.getValueAt(i, 3);

                    try (PreparedStatement stmt = conn.prepareStatement(
                            "SELECT product_name, stock FROM tb_product WHERE id = ? FOR UPDATE")) {
                        stmt.setInt(1, productId);
                        ResultSet rs = stmt.executeQuery();

                        if (rs.next()) {
                            int stock = rs.getInt("stock");
                            if (stock < quantity) {
                                JOptionPane.showMessageDialog(this,
                                        "商品 " + rs.getString("product_name") + " 库存不足，当前库存: " + stock + "，需要: " + quantity,
                                        "库存不足", JOptionPane.ERROR_MESSAGE);
                                conn.rollback();
                                return;
                            }
                        } else {
                            JOptionPane.showMessageDialog(this, "商品不存在", "错误", JOptionPane.ERROR_MESSAGE);
                            conn.rollback();
                            return;
                        }
                    }
                }

                // 确认结算
                int confirm = JOptionPane.showConfirmDialog(this,
                        "确认结算？总金额: " + totalLabel.getText(),
                        "确认结算", JOptionPane.YES_NO_OPTION);

                if (confirm != JOptionPane.YES_OPTION) {
                    conn.rollback();
                    return;
                }

                // 创建销售记录
                Timestamp saleTime = new Timestamp(System.currentTimeMillis());

                for (int i = 0; i < tableModel.getRowCount(); i++) {
                    int productId = (int) tableModel.getValueAt(i, 0);
                    int quantity = (int) tableModel.getValueAt(i, 3);
                    float salePrice = (float) tableModel.getValueAt(i, 2);
                    String productName = (String) tableModel.getValueAt(i, 1);

                    // 获取商品进价和分类ID
                    float purchasePrice = 0;
                    int groupId = 0;
                    try (PreparedStatement stmt = conn.prepareStatement(
                            "SELECT p.purchase_price, p.group_id " +
                                    "FROM tb_product p WHERE p.id = ?")) {

                        stmt.setInt(1, productId);
                        ResultSet rs = stmt.executeQuery();
                        if (rs.next()) {
                            purchasePrice = rs.getFloat("purchase_price");
                            groupId = rs.getInt("group_id");
                        }
                    }

                    // 计算销售额和净利润
                    float saleVolume = salePrice * quantity;
                    float netProfit = (salePrice - purchasePrice) * quantity;

                    // 插入销售记录
                    try (PreparedStatement stmt = conn.prepareStatement(
                            "INSERT INTO tb_sale (product_id, product_name, group_id, purchase_price, sale_price, " +
                                    "sale_count, sale_volume, net_profit, generate_time) " +
                                    "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)")) {

                        stmt.setInt(1, productId);
                        stmt.setString(2, productName);
                        stmt.setInt(3, groupId);
                        stmt.setFloat(4, purchasePrice);
                        stmt.setFloat(5, salePrice);
                        stmt.setInt(6, quantity);
                        stmt.setFloat(7, saleVolume);
                        stmt.setFloat(8, netProfit);
                        stmt.setTimestamp(9, saleTime);
                        stmt.executeUpdate();
                    }

                    // 更新商品库存
                    try (PreparedStatement stmt = conn.prepareStatement(
                            "UPDATE tb_product SET stock = stock - ?, sale_count = sale_count + ? WHERE id = ?")) {

                        stmt.setInt(1, quantity);
                        stmt.setInt(2, quantity);
                        stmt.setInt(3, productId);
                        stmt.executeUpdate();
                    }
                }

                conn.commit();
                JOptionPane.showMessageDialog(this, "结算成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                clearCart();

                // 刷新商品和销售面板
                productPanel.loadProducts();
                salesPanel.loadSales();

            } catch (SQLException ex) {
                ex.printStackTrace();
                try {
                    Connection conn = getConnection();
                    if (conn != null && !conn.getAutoCommit()) {
                        conn.rollback();
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                JOptionPane.showMessageDialog(this, "结算失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }

        private void clearCart() {
            tableModel.setRowCount(0);
            totalLabel.setText("总计: 0.00元");
            productIdField.setText("");
            quantityField.setText("");
        }
    }

    // ========================== 商品分类管理面板 ==========================
    class CategoryPanel extends JPanel {
        private JTable categoryTable;
        private CategoryTableModel tableModel;

        public CategoryPanel() {
            setLayout(new BorderLayout());

            // 顶部工具栏
            JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

            JButton addButton = new JButton("添加分类");
            addButton.addActionListener(e -> showAddCategoryDialog());
            topPanel.add(addButton);

            JButton editButton = new JButton("编辑分类");
            editButton.addActionListener(e -> showEditCategoryDialog());
            topPanel.add(editButton);

            JButton deleteButton = new JButton("删除分类");
            deleteButton.addActionListener(e -> deleteCategory());  // 修复拼写错误
            topPanel.add(deleteButton);

            JButton refreshButton = new JButton("刷新数据");
            refreshButton.addActionListener(e -> loadCategories());
            topPanel.add(refreshButton);

            add(topPanel, BorderLayout.NORTH);

            // 分类表格
            tableModel = new CategoryTableModel();
            categoryTable = new JTable(tableModel);
            categoryTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            JScrollPane scrollPane = new JScrollPane(categoryTable);
            add(scrollPane, BorderLayout.CENTER);

            // 加载分类数据
            loadCategories();
        }

        private void loadCategories() {
            tableModel.clear();
            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT id, group_name FROM tb_group")) {

                while (rs.next()) {
                    Category category = new Category(
                            rs.getInt("id"),
                            rs.getString("group_name")
                    );
                    tableModel.addCategory(category);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void showAddCategoryDialog() {
            AddEditCategoryDialog dialog = new AddEditCategoryDialog(null, "添加分类");
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadCategories();
            }
        }

        private void showEditCategoryDialog() {
            int selectedRow = categoryTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请先选择要编辑的分类", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            Category category = tableModel.getCategoryAt(selectedRow);
            AddEditCategoryDialog dialog = new AddEditCategoryDialog(category, "编辑分类");
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadCategories();
            }
        }

        private void deleteCategory() {
            int selectedRow = categoryTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请先选择要删除的分类", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            Category category = tableModel.getCategoryAt(selectedRow);

            // 检查是否有商品使用该分类
            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "SELECT COUNT(*) FROM tb_product WHERE group_id = ?")) {

                stmt.setInt(1, category.getId());
                ResultSet rs = stmt.executeQuery();
                if (rs.next() && rs.getInt(1) > 0) {  // 修复拼写错误
                    JOptionPane.showMessageDialog(this,
                            "该分类下还有商品，无法删除",
                            "错误", JOptionPane.ERROR_MESSAGE);
                    return;
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }

            int confirm = JOptionPane.showConfirmDialog(this,
                    "确定要删除这个分类吗？", "确认删除", JOptionPane.YES_NO_OPTION);
            if (confirm != JOptionPane.YES_OPTION) {
                return;
            }

            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "DELETE FROM tb_group WHERE id = ?")) {

                stmt.setInt(1, category.getId());
                int rows = stmt.executeUpdate();
                if (rows > 0) {
                    JOptionPane.showMessageDialog(this, "分类删除成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                    loadCategories();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(this, "删除失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }

        class Category {
            private int id;
            private String name;

            public Category(int id, String name) {
                this.id = id;
                this.name = name;
            }

            // Getters
            public int getId() { return id; }
            public String getName() { return name; }
        }

        class CategoryTableModel extends AbstractTableModel {
            private String[] columnNames = {"ID", "分类名称"};
            private List<Category> categories = new ArrayList<>();

            public void addCategory(Category category) {
                categories.add(category);
            }

            public void clear() {
                categories.clear();
            }

            public Category getCategoryAt(int row) {
                return categories.get(row);
            }

            @Override
            public int getRowCount() {
                return categories.size();
            }

            @Override
            public int getColumnCount() {
                return columnNames.length;
            }

            @Override
            public String getColumnName(int column) {
                return columnNames[column];
            }

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                Category category = categories.get(rowIndex);
                switch (columnIndex) {
                    case 0: return category.getId();
                    case 1: return category.getName();
                    default: return null;
                }
            }
        }

        class AddEditCategoryDialog extends JDialog {
            private boolean success = false;
            private JTextField nameField;

            public AddEditCategoryDialog(Category category, String title) {
                setTitle(title);
                setSize(300, 150);
                setModal(true);
                setLocationRelativeTo(CategoryPanel.this);

                JPanel panel = new JPanel(new GridLayout(2, 2, 10, 10));
                panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

                // 分类名称
                panel.add(new JLabel("分类名称:"));
                nameField = new JTextField();
                panel.add(nameField);

                // 按钮面板
                JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
                JButton saveButton = new JButton("保存");
                saveButton.addActionListener(e -> saveCategory(category));
                buttonPanel.add(saveButton);

                JButton cancelButton = new JButton("取消");
                cancelButton.addActionListener(e -> dispose());
                buttonPanel.add(cancelButton);

                // 设置初始值（如果是编辑）
                if (category != null) {
                    nameField.setText(category.getName());
                }

                add(panel, BorderLayout.CENTER);
                add(buttonPanel, BorderLayout.SOUTH);
            }

            private void saveCategory(Category originalCategory) {
                try {
                    String name = nameField.getText().trim();

                    if (name.isEmpty()) {
                        JOptionPane.showMessageDialog(this, "分类名称不能为空", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    if (originalCategory == null) {
                        // 添加新分类
                        try (Connection conn = getConnection();
                             PreparedStatement stmt = conn.prepareStatement(
                                     "INSERT INTO tb_group (group_name) VALUES (?)")) {

                            stmt.setString(1, name);
                            int rows = stmt.executeUpdate();
                            if (rows > 0) {
                                success = true;
                                JOptionPane.showMessageDialog(this, "分类添加成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                                dispose();
                            }
                        }
                    } else {
                        // 更新现有分类
                        try (Connection conn = getConnection();
                             PreparedStatement stmt = conn.prepareStatement(
                                     "UPDATE tb_group SET group_name = ? WHERE id = ?")) {

                            stmt.setString(1, name);
                            stmt.setInt(2, originalCategory.getId());
                            int rows = stmt.executeUpdate();
                            if (rows > 0) {
                                success = true;
                                JOptionPane.showMessageDialog(this, "分类更新成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                                dispose();
                            }
                        }
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(this, "保存失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                }
            }

            public boolean isSuccess() {
                return success;
            }
        }
    }



    // ========================== 商品管理面板 ==========================
    class ProductPanel extends JPanel {
        private JTable productTable;
        private ProductTableModel tableModel;
        private JComboBox<String> groupFilter;
        // 添加商品名称查询字段
        private JTextField productNameSearchField;

        public ProductPanel() {

            setLayout(new BorderLayout());

            // 顶部工具栏
            JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

            // 分组筛选
            topPanel.add(new JLabel("商品分类:"));
            groupFilter = new JComboBox<>();
            groupFilter.addItem("所有分类");
            loadGroups();
            groupFilter.addActionListener(e -> filterProducts());
            topPanel.add(groupFilter);

            // 添加按钮
            JButton addButton = new JButton("添加商品");
            addButton.addActionListener(e -> showAddProductDialog());
            topPanel.add(addButton);

            // 在顶部工具栏中添加商品名称查询功能
            topPanel.add(new JLabel("商品名称:"));
            productNameSearchField = new JTextField(15);
            topPanel.add(productNameSearchField);

            JButton searchButton = new JButton("查询");
            searchButton.addActionListener(e -> searchProductByName());
            topPanel.add(searchButton);

            // 编辑按钮
            JButton editButton = new JButton("编辑商品");
            editButton.addActionListener(e -> showEditProductDialog());
            topPanel.add(editButton);



            // 删除按钮
            JButton deleteButton = new JButton("删除商品");
            deleteButton.addActionListener(e -> deleteProduct());
            topPanel.add(deleteButton);

            // 刷新按钮
            JButton refreshButton = new JButton("刷新数据");
            refreshButton.addActionListener(e -> loadProducts());
            topPanel.add(refreshButton);

            add(topPanel, BorderLayout.NORTH);

            // 商品表格
            tableModel = new ProductTableModel();
            productTable = new JTable(tableModel);
            productTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            JScrollPane scrollPane = new JScrollPane(productTable);
            add(scrollPane, BorderLayout.CENTER);

            // 加载商品数据
            loadProducts();
        }

        // 新增：按商品名称查询方法
        private void searchProductByName() {
            String productName = productNameSearchField.getText().trim();
            if (productName.isEmpty()) {
                loadProducts(); // 如果为空则加载全部
                return;
            }

            tableModel.clear();
            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "SELECT p.*, g.group_name, pr.provider_name " +
                                 "FROM tb_product p " +
                                 "JOIN tb_group g ON p.group_id = g.id " +
                                 "JOIN tb_provider pr ON p.provider_id = pr.id " +
                                 "WHERE p.product_name LIKE ?")) {

                stmt.setString(1, "%" + productName + "%");
                ResultSet rs = stmt.executeQuery();

                while (rs.next()) {
                    Product product = new Product(
                            rs.getInt("id"),
                            rs.getInt("group_id"),
                            rs.getString("group_name"),
                            rs.getInt("provider_id"),
                            rs.getString("provider_name"),
                            rs.getString("product_name"),
                            rs.getDate("yield_date"),
                            rs.getString("product_factory"),
                            rs.getFloat("purchase_price"),
                            rs.getInt("stock"),
                            rs.getFloat("sale_price"),
                            rs.getInt("sale_count"),
                            rs.getDate("create_date")
                    );
                    tableModel.addProduct(product);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void loadGroups() {
            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT group_name FROM tb_group")) {

                while (rs.next()) {
                    groupFilter.addItem(rs.getString("group_name"));
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }

        private void loadProducts() {
            tableModel.clear();
            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery(
                         "SELECT p.*, g.group_name, pr.provider_name " +
                                 "FROM tb_product p " +
                                 "JOIN tb_group g ON p.group_id = g.id " +
                                 "JOIN tb_provider pr ON p.provider_id = pr.id")) {

                while (rs.next()) {
                    Product product = new Product(
                            rs.getInt("id"),
                            rs.getInt("group_id"),
                            rs.getString("group_name"),
                            rs.getInt("provider_id"),
                            rs.getString("provider_name"),
                            rs.getString("product_name"),
                            rs.getDate("yield_date"),
                            rs.getString("product_factory"),
                            rs.getFloat("purchase_price"),
                            rs.getInt("stock"),
                            rs.getFloat("sale_price"),
                            rs.getInt("sale_count"),
                            rs.getDate("create_date")
                    );
                    tableModel.addProduct(product);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void filterProducts() {
            String selectedGroup = (String) groupFilter.getSelectedItem();
            if ("所有分类".equals(selectedGroup)) {
                loadProducts();
                return;
            }

            tableModel.clear();
            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "SELECT p.*, g.group_name, pr.provider_name " +
                                 "FROM tb_product p " +
                                 "JOIN tb_group g ON p.group_id = g.id " +
                                 "JOIN tb_provider pr ON p.provider_id = pr.id " +
                                 "WHERE g.group_name = ?")) {

                stmt.setString(1, selectedGroup);
                ResultSet rs = stmt.executeQuery();

                while (rs.next()) {
                    Product product = new Product(
                            rs.getInt("id"),
                            rs.getInt("group_id"),
                            rs.getString("group_name"),
                            rs.getInt("provider_id"),
                            rs.getString("provider_name"),
                            rs.getString("product_name"),
                            rs.getDate("yield_date"),
                            rs.getString("product_factory"),
                            rs.getFloat("purchase_price"),
                            rs.getInt("stock"),
                            rs.getFloat("sale_price"),
                            rs.getInt("sale_count"),
                            rs.getDate("create_date")
                    );
                    tableModel.addProduct(product);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void showAddProductDialog() {
            AddEditProductDialog dialog = new AddEditProductDialog(null, "添加商品");
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadProducts();
            }
        }

        private void showEditProductDialog() {
            int selectedRow = productTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请先选择要编辑的商品", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            Product product = tableModel.getProductAt(selectedRow);
            AddEditProductDialog dialog = new AddEditProductDialog(product, "编辑商品");
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadProducts();
            }
        }

        private void deleteProduct() {
            int selectedRow = productTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请先选择要删除的商品", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            int confirm = JOptionPane.showConfirmDialog(this,
                    "确定要删除这个商品吗？", "确认删除", JOptionPane.YES_NO_OPTION);
            if (confirm != JOptionPane.YES_OPTION) {
                return;
            }

            Product product = tableModel.getProductAt(selectedRow);
            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "DELETE FROM tb_product WHERE id = ?")) {

                stmt.setInt(1, product.getId());
                int rows = stmt.executeUpdate();
                if (rows > 0) {
                    JOptionPane.showMessageDialog(this, "商品删除成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                    loadProducts();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(this, "删除失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }

        class ProductTableModel extends AbstractTableModel {
            private String[] columnNames = {
                    "ID", "商品名称", "分类", "供应商", "生产日期", "生产工厂",
                    "进价", "库存", "售价", "销量", "创建日期"
            };

            private List<Product> products = new ArrayList<>();

            public void addProduct(Product product) {
                products.add(product);
            }

            public void clear() {
                products.clear();
            }

            public Product getProductAt(int row) {
                return products.get(row);
            }

            @Override
            public int getRowCount() {
                return products.size();
            }

            @Override
            public int getColumnCount() {
                return columnNames.length;
            }

            @Override
            public String getColumnName(int column) {
                return columnNames[column];
            }

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                Product product = products.get(rowIndex);
                switch (columnIndex) {
                    case 0: return product.getId();
                    case 1: return product.getName();
                    case 2: return product.getGroupName();
                    case 3: return product.getProviderName();
                    case 4: return new SimpleDateFormat("yyyy-MM-dd").format(product.getYieldDate());
                    case 5: return product.getFactory();
                    case 6: return product.getPurchasePrice();
                    case 7: return product.getStock();
                    case 8: return product.getSalePrice();
                    case 9: return product.getSaleCount();
                    case 10: return new SimpleDateFormat("yyyy-MM-dd").format(product.getCreateDate());
                    default: return null;
                }
            }
        }

        class AddEditProductDialog extends JDialog {
            private boolean success = false;
            private JTextField nameField, factoryField, purchasePriceField, stockField, salePriceField;
            private JComboBox<String> groupCombo, providerCombo;
            private JFormattedTextField yieldDateField, createDateField;

            public AddEditProductDialog(Product product, String title) {
                setTitle(title);
                setSize(500, 400);
                setModal(true);
                setLocationRelativeTo(ProductPanel.this);

                JPanel panel = new JPanel(new GridLayout(9, 2, 10, 10));
                panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

                // 商品名称
                panel.add(new JLabel("商品名称:"));
                nameField = new JTextField();
                panel.add(nameField);

                // 分类
                panel.add(new JLabel("商品分类:"));
                groupCombo = new JComboBox<>();
                loadGroupsToCombo();
                panel.add(groupCombo);

                // 供应商
                panel.add(new JLabel("供应商:"));
                providerCombo = new JComboBox<>();
                loadProvidersToCombo();
                panel.add(providerCombo);

                // 生产日期
                panel.add(new JLabel("生产日期:"));
                yieldDateField = new JFormattedTextField(new SimpleDateFormat("yyyy-MM-dd"));
                yieldDateField.setValue(new Date());
                panel.add(yieldDateField);

                // 生产工厂
                panel.add(new JLabel("生产工厂:"));
                factoryField = new JTextField();
                panel.add(factoryField);

                // 进价
                panel.add(new JLabel("进价:"));
                purchasePriceField = new JTextField();
                panel.add(purchasePriceField);

                // 库存
                panel.add(new JLabel("库存:"));
                stockField = new JTextField();
                panel.add(stockField);

                // 售价
                panel.add(new JLabel("售价:"));
                salePriceField = new JTextField();
                panel.add(salePriceField);

                // 按钮面板
                JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
                JButton saveButton = new JButton("保存");
                saveButton.addActionListener(e -> saveProduct(product));
                buttonPanel.add(saveButton);

                JButton cancelButton = new JButton("取消");
                cancelButton.addActionListener(e -> dispose());
                buttonPanel.add(cancelButton);

                // 设置初始值（如果是编辑）
                if (product != null) {
                    nameField.setText(product.getName());
                    groupCombo.setSelectedItem(product.getGroupName());
                    providerCombo.setSelectedItem(product.getProviderName());
                    yieldDateField.setValue(product.getYieldDate());
                    factoryField.setText(product.getFactory());
                    purchasePriceField.setText(String.valueOf(product.getPurchasePrice()));
                    stockField.setText(String.valueOf(product.getStock()));
                    salePriceField.setText(String.valueOf(product.getSalePrice()));
                }

                add(panel, BorderLayout.CENTER);
                add(buttonPanel, BorderLayout.SOUTH);
            }

            private void loadGroupsToCombo() {
                try (Connection conn = getConnection();
                     Statement stmt = conn.createStatement();
                     ResultSet rs = stmt.executeQuery("SELECT group_name FROM tb_group")) {

                    while (rs.next()) {
                        groupCombo.addItem(rs.getString("group_name"));
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }

            private void loadProvidersToCombo() {
                try (Connection conn = getConnection();
                     Statement stmt = conn.createStatement();
                     ResultSet rs = stmt.executeQuery("SELECT provider_name FROM tb_provider")) {

                    while (rs.next()) {
                        providerCombo.addItem(rs.getString("provider_name"));
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }

            private void saveProduct(Product originalProduct) {
                try {
                    String name = nameField.getText();
                    String groupName = (String) groupCombo.getSelectedItem();
                    String providerName = (String) providerCombo.getSelectedItem();
                    Date yieldDate = (Date) yieldDateField.getValue();
                    String factory = factoryField.getText();
                    float purchasePrice = Float.parseFloat(purchasePriceField.getText());
                    int stock = Integer.parseInt(stockField.getText());
                    float salePrice = Float.parseFloat(salePriceField.getText());

                    // 获取分类ID
                    int groupId = getGroupId(groupName);
                    if (groupId == -1) {
                        JOptionPane.showMessageDialog(this, "无效的商品分类", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    // 获取供应商ID
                    int providerId = getProviderId(providerName);
                    if (providerId == -1) {
                        JOptionPane.showMessageDialog(this, "无效的供应商", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    if (originalProduct == null) {
                        // 添加新商品
                        try (Connection conn = getConnection();
                             PreparedStatement stmt = conn.prepareStatement(
                                     "INSERT INTO tb_product (group_id, provider_id, product_name, " +
                                             "yield_date, product_factory, purchase_price, stock, sale_price, " +
                                             "sale_count, create_date) VALUES (?, ?, ?, ?, ?, ?, ?, ?, 0, NOW())")) {

                            stmt.setInt(1, groupId);
                            stmt.setInt(2, providerId);
                            stmt.setString(3, name);
                            stmt.setDate(4, new java.sql.Date(yieldDate.getTime()));
                            stmt.setString(5, factory);
                            stmt.setFloat(6, purchasePrice);
                            stmt.setInt(7, stock);
                            stmt.setFloat(8, salePrice);

                            int rows = stmt.executeUpdate();
                            if (rows > 0) {
                                success = true;
                                JOptionPane.showMessageDialog(this, "商品添加成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                                dispose();
                            }
                        }
                    } else {
                        // 更新现有商品
                        try (Connection conn = getConnection();
                             PreparedStatement stmt = conn.prepareStatement(
                                     "UPDATE tb_product SET group_id = ?, provider_id = ?, product_name = ?, " +
                                             "yield_date = ?, product_factory = ?, purchase_price = ?, stock = ?, " +
                                             "sale_price = ? WHERE id = ?")) {

                            stmt.setInt(1, groupId);
                            stmt.setInt(2, providerId);
                            stmt.setString(3, name);
                            stmt.setDate(4, new java.sql.Date(yieldDate.getTime()));
                            stmt.setString(5, factory);
                            stmt.setFloat(6, purchasePrice);
                            stmt.setInt(7, stock);
                            stmt.setFloat(8, salePrice);
                            stmt.setInt(9, originalProduct.getId());

                            int rows = stmt.executeUpdate();
                            if (rows > 0) {
                                success = true;
                                JOptionPane.showMessageDialog(this, "商品更新成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                                dispose();
                            }
                        }
                    }
                } catch (Exception ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(this, "保存失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                }
            }

            private int getGroupId(String groupName) {
                try (Connection conn = getConnection();
                     PreparedStatement stmt = conn.prepareStatement(
                             "SELECT id FROM tb_group WHERE group_name = ?")) {

                    stmt.setString(1, groupName);
                    ResultSet rs = stmt.executeQuery();
                    if (rs.next()) {
                        return rs.getInt("id");
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
                return -1;
            }

            private int getProviderId(String providerName) {
                try (Connection conn = getConnection();
                     PreparedStatement stmt = conn.prepareStatement(
                             "SELECT id FROM tb_provider WHERE provider_name = ?")) {

                    stmt.setString(1, providerName);
                    ResultSet rs = stmt.executeQuery();
                    if (rs.next()) {
                        return rs.getInt("id");
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
                return -1;
            }

            public boolean isSuccess() {
                return success;
            }
        }
    }

    // ========================== 销售管理面板 ==========================
    class SalesPanel extends JPanel {


        private JTable salesTable;
        private SalesTableModel tableModel;
        private JComboBox<String> timeFilter;
        private JButton reportButton;
        private JComboBox<String> groupFilter; // 新增商品分类下拉框

        public SalesPanel() {


            setLayout(new BorderLayout());

            // 顶部工具栏
            JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

            // 添加结算按钮
            JButton checkoutButton = new JButton("结算");
            checkoutButton.addActionListener(e -> showCheckoutDialog());
            topPanel.add(checkoutButton);



            // 原有按钮（时间筛选、添加销售记录等）
            topPanel.add(new JLabel("时间范围:"));
            timeFilter = new JComboBox<>(new String[]{"全部", "今天", "本周", "本月", "本季度", "本年"});
            timeFilter.addActionListener(e -> filterSales());
            topPanel.add(timeFilter);

            JButton addButton = new JButton("添加销售记录");
            addButton.addActionListener(e -> showAddSaleDialog());
            topPanel.add(addButton);

            reportButton = new JButton("生成销售报表");
            reportButton.addActionListener(e -> generateSalesReport());
            topPanel.add(reportButton);

            JButton refreshButton = new JButton("刷新数据");
            refreshButton.addActionListener(e -> loadSales());
            topPanel.add(refreshButton);

            // 添加商品分类筛选
            topPanel.add(new JLabel("商品分类:"));
            groupFilter = new JComboBox<>();
            groupFilter.addItem("所有分类");
            loadGroups(); // 加载商品分类
            topPanel.add(groupFilter);

            JButton groupSearchButton = new JButton("分类查询");
            groupSearchButton.addActionListener(e -> filterSalesByGroup());
            topPanel.add(groupSearchButton);

            add(topPanel, BorderLayout.NORTH);

            // 销售表格
            tableModel = new SalesTableModel();
            salesTable = new JTable(tableModel);
            salesTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            JScrollPane scrollPane = new JScrollPane(salesTable);
            add(scrollPane, BorderLayout.CENTER);

            // 加载销售数据
            loadSales();
        }

        // 新增：加载商品分类方法
        private void loadGroups() {
            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT group_name FROM tb_group")) {

                while (rs.next()) {
                    groupFilter.addItem(rs.getString("group_name"));
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }

        // 新增：按商品分类查询方法
        private void filterSalesByGroup() {
            String groupName = (String) groupFilter.getSelectedItem();
            if (groupName == null || "所有分类".equals(groupName)) {
                loadSales(); // 加载全部
                return;
            }

            tableModel.clear();
            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "SELECT s.*, p.product_name, g.group_name " +
                                 "FROM tb_sale s " +
                                 "JOIN tb_product p ON s.product_id = p.id " +
                                 "JOIN tb_group g ON p.group_id = g.id " +
                                 "WHERE g.group_name = ?")) {

                stmt.setString(1, groupName);
                ResultSet rs = stmt.executeQuery();

                while (rs.next()) {
                    Sale sale = new Sale(
                            rs.getInt("sale_id"),
                            rs.getInt("product_id"),
                            rs.getString("product_name"),
                            rs.getInt("group_id"),
                            rs.getString("group_name"),
                            rs.getFloat("purchase_price"),
                            rs.getFloat("sale_price"),
                            rs.getInt("sale_count"),
                            rs.getFloat("sale_volume"),
                            rs.getFloat("net_profit"),
                            rs.getTimestamp("generate_time")
                    );
                    tableModel.addSale(sale);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        // 结算对话框
        private void showCheckoutDialog() {
            CheckoutDialog dialog = new CheckoutDialog();
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadSales(); // 刷新销售数据
            }
        }

        // 结算对话框内部类
        class CheckoutDialog extends JDialog {
            private boolean success = false;
            private JTextField productIdField;
            private JTextField quantityField;

            public CheckoutDialog() {
                setTitle("结算");
                setSize(400, 200);
                setModal(true);
                setLocationRelativeTo(SalesPanel.this);

                JPanel panel = new JPanel(new GridLayout(3, 2, 10, 10));
                panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

                // 商品编号
                panel.add(new JLabel("商品编号:"));
                productIdField = new JTextField();
                panel.add(productIdField);

                // 购买数量
                panel.add(new JLabel("购买数量:"));
                quantityField = new JTextField();
                panel.add(quantityField);

                // 按钮面板
                JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
                JButton saveButton = new JButton("确认结算");
                saveButton.addActionListener(e -> processCheckout());
                buttonPanel.add(saveButton);

                JButton cancelButton = new JButton("取消");
                cancelButton.addActionListener(e -> dispose());
                buttonPanel.add(cancelButton);

                add(panel, BorderLayout.CENTER);
                add(buttonPanel, BorderLayout.SOUTH);
            }

            // 处理结算逻辑
            private void processCheckout() {
                try {
                    int productId = Integer.parseInt(productIdField.getText());
                    int quantity = Integer.parseInt(quantityField.getText());

                    if (quantity <= 0) {
                        JOptionPane.showMessageDialog(this, "购买数量必须大于0", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    // 获取商品信息
                    Product product = getProductById(productId);
                    if (product == null) {
                        JOptionPane.showMessageDialog(this, "未找到商品信息", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    // 检查库存
                    if (product.getStock() < quantity) {
                        JOptionPane.showMessageDialog(this, "库存不足，当前库存: " + product.getStock(), "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    // 计算销售额和净利润
                    float saleVolume = product.getSalePrice() * quantity;
                    float netProfit = (product.getSalePrice() - product.getPurchasePrice()) * quantity;

                    try (Connection conn = getConnection()) {
                        conn.setAutoCommit(false); // 开启事务

                        // 1. 添加销售记录
                        try (PreparedStatement saleStmt = conn.prepareStatement(
                                "INSERT INTO tb_sale (product_id, product_name, group_id, " +
                                        "purchase_price, sale_price, sale_count, sale_volume, " +
                                        "net_profit, generate_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())")) {

                            saleStmt.setInt(1, productId);
                            saleStmt.setString(2, product.getName());
                            saleStmt.setInt(3, product.getGroupId());
                            saleStmt.setFloat(4, product.getPurchasePrice());
                            saleStmt.setFloat(5, product.getSalePrice());
                            saleStmt.setInt(6, quantity);
                            saleStmt.setFloat(7, saleVolume);
                            saleStmt.setFloat(8, netProfit);

                            saleStmt.executeUpdate();
                        }

                        // 2. 更新商品库存和销量
                        try (PreparedStatement productStmt = conn.prepareStatement(
                                "UPDATE tb_product SET stock = stock - ?, sale_count = sale_count + ? WHERE id = ?")) {

                            productStmt.setInt(1, quantity);
                            productStmt.setInt(2, quantity);
                            productStmt.setInt(3, productId);
                            productStmt.executeUpdate();
                        }

                        conn.commit(); // 提交事务
                        success = true;
                        JOptionPane.showMessageDialog(this, "结算成功！", "成功", JOptionPane.INFORMATION_MESSAGE);
                        dispose();
                    } catch (SQLException ex) {
                        JOptionPane.showMessageDialog(this, "结算失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                        ex.printStackTrace();
                    }
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(this, "请输入有效的数字", "错误", JOptionPane.ERROR_MESSAGE);
                }
            }

            // 根据商品ID获取商品信息
            private Product getProductById(int id) {
                try (Connection conn = getConnection();
                     PreparedStatement stmt = conn.prepareStatement(
                             "SELECT * FROM tb_product WHERE id = ?")) {

                    stmt.setInt(1, id);
                    ResultSet rs = stmt.executeQuery();
                    if (rs.next()) {
                        return new Product(
                                rs.getInt("id"),
                                rs.getInt("group_id"),
                                null,
                                rs.getInt("provider_id"),
                                null,
                                rs.getString("product_name"),
                                rs.getDate("yield_date"),
                                rs.getString("product_factory"),
                                rs.getFloat("purchase_price"),
                                rs.getInt("stock"),
                                rs.getFloat("sale_price"),
                                rs.getInt("sale_count"),
                                rs.getDate("create_date")
                        );
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
                return null;
            }

            public boolean isSuccess() {
                return success;
            }
        }



        private void loadSales() {
            tableModel.clear();
            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery(
                         "SELECT s.*, p.product_name, g.group_name " +
                                 "FROM tb_sale s " +
                                 "JOIN tb_product p ON s.product_id = p.id " +
                                 "JOIN tb_group g ON p.group_id = g.id")) {

                while (rs.next()) {
                    Sale sale = new Sale(
                            rs.getInt("sale_id"),
                            rs.getInt("product_id"),
                            rs.getString("product_name"),
                            rs.getInt("group_id"),
                            rs.getString("group_name"),
                            rs.getFloat("purchase_price"),
                            rs.getFloat("sale_price"),
                            rs.getInt("sale_count"),
                            rs.getFloat("sale_volume"),
                            rs.getFloat("net_profit"),
                            rs.getTimestamp("generate_time")
                    );
                    tableModel.addSale(sale);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void filterSales() {
            String filter = (String) timeFilter.getSelectedItem();
            if ("全部".equals(filter)) {
                loadSales();
                return;
            }

            tableModel.clear();
            String sql = "SELECT s.*, p.product_name, g.group_name " +
                    "FROM tb_sale s " +
                    "JOIN tb_product p ON s.product_id = p.id " +
                    "JOIN tb_group g ON p.group_id = g.id ";

            switch (filter) {
                case "今天":
                    sql += "WHERE DATE(generate_time) = CURDATE()";
                    break;
                case "本周":
                    sql += "WHERE YEARWEEK(generate_time, 1) = YEARWEEK(CURDATE(), 1)";
                    break;
                case "本月":
                    sql += "WHERE MONTH(generate_time) = MONTH(CURDATE()) AND YEAR(generate_time) = YEAR(CURDATE())";
                    break;
                case "本季度":
                    sql += "WHERE QUARTER(generate_time) = QUARTER(CURDATE()) AND YEAR(generate_time) = YEAR(CURDATE())";
                    break;
                case "本年":
                    sql += "WHERE YEAR(generate_time) = YEAR(CURDATE())";
                    break;
            }

            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery(sql)) {

                while (rs.next()) {
                    Sale sale = new Sale(
                            rs.getInt("sale_id"),
                            rs.getInt("product_id"),
                            rs.getString("product_name"),
                            rs.getInt("group_id"),
                            rs.getString("group_name"),
                            rs.getFloat("purchase_price"),
                            rs.getFloat("sale_price"),
                            rs.getInt("sale_count"),
                            rs.getFloat("sale_volume"),
                            rs.getFloat("net_profit"),
                            rs.getTimestamp("generate_time")
                    );
                    tableModel.addSale(sale);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void showAddSaleDialog() {
            AddSaleDialog dialog = new AddSaleDialog();
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadSales();
            }
        }



        private void generateSalesReport() {
            // 使用多线程生成报表，避免界面卡顿
            new Thread(() -> {
                reportButton.setEnabled(false);
                reportButton.setText("生成中...");

                try {
                    // 获取销售数据
                    List<Sale> sales = getSalesData();

                    // 生成报表图片
                    File reportImage = createSalesReportImage(sales);

                    // 显示生成的图片
                    SwingUtilities.invokeLater(() -> {
                        ImageViewer viewer = new ImageViewer(reportImage);
                        viewer.setVisible(true);
                    });

                } catch (Exception ex) {
                    ex.printStackTrace();
                    SwingUtilities.invokeLater(() ->
                            JOptionPane.showMessageDialog(SalesPanel.this,
                                    "生成报表失败: " + ex.getMessage(),
                                    "错误", JOptionPane.ERROR_MESSAGE));
                } finally {
                    SwingUtilities.invokeLater(() -> {
                        reportButton.setText("生成销售报表");
                        reportButton.setEnabled(true);
                    });
                }
            }).start();
        }

        // 获取销售数据
        private List<Sale> getSalesData() throws SQLException {
            List<Sale> sales = new ArrayList<>();
            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery(
                         "SELECT s.*, p.product_name, g.group_name " +
                                 "FROM tb_sale s " +
                                 "JOIN tb_product p ON s.product_id = p.id " +
                                 "JOIN tb_group g ON p.group_id = g.id " +
                                 "ORDER BY s.generate_time DESC")) {

                while (rs.next()) {
                    sales.add(new Sale(
                            rs.getInt("sale_id"),
                            rs.getInt("product_id"),
                            rs.getString("product_name"),
                            rs.getInt("group_id"),
                            rs.getString("group_name"),
                            rs.getFloat("purchase_price"),
                            rs.getFloat("sale_price"),
                            rs.getInt("sale_count"),
                            rs.getFloat("sale_volume"),
                            rs.getFloat("net_profit"),
                            rs.getTimestamp("generate_time")
                    ));
                }
            }
            return sales;
        }

        // 创建销售报表图片（改进版）
        private File createSalesReportImage(List<Sale> sales) throws IOException {
            // 基本参数设置
            int width = 800;
            int rowHeight = 30;
            int headerHeight = 120;
            int footerHeight = 100;

            // 动态计算图片高度
            int tableHeight = sales.size() * rowHeight;
            int height = headerHeight + tableHeight + footerHeight;

            // 确保最小高度
            height = Math.max(height, 600);

            // 创建缓冲图像
            BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = image.createGraphics();

            // 启用抗锯齿
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

            // 设置背景
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, width, height);

            // 设置标题
            g2d.setColor(new Color(70, 130, 180));  // 钢蓝色
            g2d.setFont(new Font("微软雅黑", Font.BOLD, 24));
            g2d.drawString("泡泡玛特销售报表", 300, 40);

            // 设置副标题
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm");
            g2d.setColor(Color.DARK_GRAY);
            g2d.setFont(new Font("微软雅黑", Font.PLAIN, 14));
            g2d.drawString("生成日期: " + sdf.format(new Date()), 300, 70);
            g2d.drawString("总记录数: " + sales.size() + " 条", 300, 90);

            // 绘制表格
            int startX = 50;
            int startY = headerHeight;
            int[] colWidths = {150, 100, 80, 120, 120, 150};  // 各列宽度

            // 表头
            String[] headers = {"商品名称", "分类", "销量", "销售额", "净利润", "销售时间"};
            g2d.setFont(new Font("微软雅黑", Font.BOLD, 14));

            // 绘制表头背景
            g2d.setColor(new Color(220, 230, 240));
            g2d.fillRect(startX, startY, width - 100, rowHeight);

            // 绘制表头文字和边框
            g2d.setColor(Color.BLACK);
            int currentX = startX;
            for (int i = 0; i < headers.length; i++) {
                g2d.drawRect(currentX, startY, colWidths[i], rowHeight);
                // 文字居中
                FontMetrics fm = g2d.getFontMetrics();
                int textWidth = fm.stringWidth(headers[i]);
                g2d.drawString(headers[i], currentX + (colWidths[i] - textWidth)/2, startY + 20);
                currentX += colWidths[i];
            }

            // 表格内容
            g2d.setFont(new Font("微软雅黑", Font.PLAIN, 12));
            int currentY = startY + rowHeight;
            boolean alternate = false;  // 用于交替行颜色

            for (Sale sale : sales) {
                // 交替行背景色
                if (alternate) {
                    g2d.setColor(new Color(245, 245, 245));
                    g2d.fillRect(startX, currentY, width - 100, rowHeight);
                } else {
                    g2d.setColor(Color.WHITE);
                }
                alternate = !alternate;

                // 绘制单元格内容和边框
                g2d.setColor(Color.BLACK);
                currentX = startX;
                for (int i = 0; i < headers.length; i++) {
                    g2d.drawRect(currentX, currentY, colWidths[i], rowHeight);

                    String content = "";
                    switch (i) {
                        case 0: content = sale.getProductName(); break;
                        case 1: content = sale.getGroupName(); break;
                        case 2: content = String.valueOf(sale.getSaleCount()); break;
                        case 3: content = String.format("¥%.2f", sale.getSaleVolume()); break;
                        case 4: content = String.format("¥%.2f", sale.getNetProfit()); break;
                        case 5: content = sdf.format(sale.getGenerateTime()); break;
                    }

                    // 文字对齐处理
                    FontMetrics fm = g2d.getFontMetrics();
                    int textWidth = fm.stringWidth(content);
                    int xPos = currentX + 5;  // 默认左对齐
                    if (i >= 2) {  // 数字列右对齐
                        xPos = currentX + colWidths[i] - textWidth - 5;
                    }

                    g2d.drawString(content, xPos, currentY + 20);
                    currentX += colWidths[i];
                }
                currentY += rowHeight;
            }

            // 绘制统计信息
            float totalVolume = sales.stream().map(Sale::getSaleVolume).reduce(0f, Float::sum);
            float totalProfit = sales.stream().map(Sale::getNetProfit).reduce(0f, Float::sum);

            g2d.setColor(new Color(70, 130, 180));
            g2d.setFont(new Font("微软雅黑", Font.BOLD, 16));
            g2d.drawString("总销售额: ¥" + String.format("%,.2f", totalVolume), 50, currentY + 30);
            g2d.drawString("总净利润: ¥" + String.format("%,.2f", totalProfit), 50, currentY + 60);

            g2d.dispose();

            // 保存图片
            File reportFile = new File("sales_report_" + System.currentTimeMillis() + ".png");
            ImageIO.write(image, "png", reportFile);

            return reportFile;
        }

        // 改进的图片查看器类
        class ImageViewer extends JFrame {
            public ImageViewer(File imageFile) {
                setTitle("销售报表 - " + imageFile.getName());
                setSize(850, 650);
                setLocationRelativeTo(null);
                setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

                try {
                    BufferedImage image = ImageIO.read(imageFile);
                    JLabel label = new JLabel(new ImageIcon(image));

                    // 使用JScrollPane支持滚动
                    JScrollPane scrollPane = new JScrollPane(label);
                    scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
                    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

                    getContentPane().add(scrollPane, BorderLayout.CENTER);

                    // 添加底部按钮面板
                    JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));

                    // 打印按钮
                    JButton printButton = new JButton("打印报表");
                    printButton.addActionListener(e -> printImage(image));
                    buttonPanel.add(printButton);

                    // 保存按钮
                    JButton saveButton = new JButton("另存为...");
                    saveButton.addActionListener(e -> saveImage(image));
                    buttonPanel.add(saveButton);

                    getContentPane().add(buttonPanel, BorderLayout.SOUTH);
                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(this, "无法加载图片: " + ex.getMessage(),
                            "错误", JOptionPane.ERROR_MESSAGE);
                    dispose();
                }
            }

            private void saveImage(BufferedImage image) {
                JFileChooser fileChooser = new JFileChooser();
                fileChooser.setDialogTitle("保存销售报表");
                fileChooser.setSelectedFile(new File("sales_report.png"));

                // 添加文件过滤器
                fileChooser.setFileFilter(new FileNameExtensionFilter("PNG图片", "png"));

                if (fileChooser.showSaveDialog(this) == JFileChooser.APPROVE_OPTION) {
                    File file = fileChooser.getSelectedFile();
                    // 确保文件扩展名
                    if (!file.getName().toLowerCase().endsWith(".png")) {
                        file = new File(file.getPath() + ".png");
                    }

                    try {
                        ImageIO.write(image, "png", file);
                        JOptionPane.showMessageDialog(this, "图片已保存到:\n" + file.getAbsolutePath(),
                                "保存成功", JOptionPane.INFORMATION_MESSAGE);
                    } catch (IOException ex) {
                        JOptionPane.showMessageDialog(this, "保存失败: " + ex.getMessage(),
                                "错误", JOptionPane.ERROR_MESSAGE);
                    }
                }
            }

            private void printImage(BufferedImage image) {
                // 实现打印功能
                JOptionPane.showMessageDialog(this, "打印功能待实现", "提示", JOptionPane.INFORMATION_MESSAGE);
            }
        }

        class SalesTableModel extends AbstractTableModel {
            private String[] columnNames = {
                    "销售ID", "商品名称", "分类", "进价", "售价", "销量", "销售额", "净利润", "销售时间"
            };

            private List<Sale> sales = new ArrayList<>();

            public void addSale(Sale sale) {
                sales.add(sale);
            }

            public void clear() {
                sales.clear();
            }

            @Override
            public int getRowCount() {
                return sales.size();
            }

            @Override
            public int getColumnCount() {
                return columnNames.length;
            }

            @Override
            public String getColumnName(int column) {
                return columnNames[column];
            }

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                Sale sale = sales.get(rowIndex);
                switch (columnIndex) {
                    case 0: return sale.getSaleId();
                    case 1: return sale.getProductName();
                    case 2: return sale.getGroupName();
                    case 3: return sale.getPurchasePrice();
                    case 4: return sale.getSalePrice();
                    case 5: return sale.getSaleCount();
                    case 6: return sale.getSaleVolume();
                    case 7: return sale.getNetProfit();
                    case 8: return new SimpleDateFormat("yyyy-MM-dd HH:mm").format(sale.getGenerateTime());
                    default: return null;
                }
            }
        }

        class AddSaleDialog extends JDialog {
            private boolean success = false;
            private JComboBox<String> productCombo;
            private JTextField saleCountField;

            public AddSaleDialog() {
                setTitle("添加销售记录");
                setSize(400, 250);
                setModal(true);
                setLocationRelativeTo(SalesPanel.this);

                JPanel panel = new JPanel(new GridLayout(4, 2, 10, 10));
                panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

                // 商品选择
                panel.add(new JLabel("商品:"));
                productCombo = new JComboBox<>();
                loadProductsToCombo();
                panel.add(productCombo);

                // 销售数量
                panel.add(new JLabel("销售数量:"));
                saleCountField = new JTextField();
                panel.add(saleCountField);

                // 按钮面板
                JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
                JButton saveButton = new JButton("保存");
                saveButton.addActionListener(e -> saveSale());
                buttonPanel.add(saveButton);

                JButton cancelButton = new JButton("取消");
                cancelButton.addActionListener(e -> dispose());
                buttonPanel.add(cancelButton);

                add(panel, BorderLayout.CENTER);
                add(buttonPanel, BorderLayout.SOUTH);
            }

            private void loadProductsToCombo() {
                try (Connection conn = getConnection();
                     Statement stmt = conn.createStatement();
                     ResultSet rs = stmt.executeQuery("SELECT product_name FROM tb_product")) {

                    while (rs.next()) {
                        productCombo.addItem(rs.getString("product_name"));
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
            }

            private void saveSale() {
                try {
                    String productName = (String) productCombo.getSelectedItem();
                    int saleCount = Integer.parseInt(saleCountField.getText());

                    if (saleCount <= 0) {
                        JOptionPane.showMessageDialog(this, "销售数量必须大于0", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    // 获取商品信息
                    Product product = getProductByName(productName);
                    if (product == null) {
                        JOptionPane.showMessageDialog(this, "未找到商品信息", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    // 检查库存
                    if (product.getStock() < saleCount) {
                        JOptionPane.showMessageDialog(this, "库存不足，当前库存: " + product.getStock(),
                                "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    // 计算销售额和净利润
                    float saleVolume = product.getSalePrice() * saleCount;
                    float netProfit = (product.getSalePrice() - product.getPurchasePrice()) * saleCount;

                    try (Connection conn = getConnection()) {
                        conn.setAutoCommit(false);

                        // 1. 添加销售记录
                        try (PreparedStatement saleStmt = conn.prepareStatement(
                                "INSERT INTO tb_sale (product_id, product_name, group_id, " +
                                        "purchase_price, sale_price, sale_count, sale_volume, " +
                                        "net_profit, generate_time) VALUES (?, ?, ?, ?, ?, ?, ?, ?, NOW())")) {

                            saleStmt.setInt(1, product.getId());
                            saleStmt.setString(2, product.getName());
                            saleStmt.setInt(3, product.getGroupId());
                            saleStmt.setFloat(4, product.getPurchasePrice());
                            saleStmt.setFloat(5, product.getSalePrice());
                            saleStmt.setInt(6, saleCount);
                            saleStmt.setFloat(7, saleVolume);
                            saleStmt.setFloat(8, netProfit);

                            saleStmt.executeUpdate();
                        }

                        // 2. 更新商品库存和销量
                        try (PreparedStatement productStmt = conn.prepareStatement(
                                "UPDATE tb_product SET stock = stock - ?, sale_count = sale_count + ? WHERE id = ?")) {

                            productStmt.setInt(1, saleCount);
                            productStmt.setInt(2, saleCount);
                            productStmt.setInt(3, product.getId());

                            productStmt.executeUpdate();
                        }

                        conn.commit();
                        success = true;
                        JOptionPane.showMessageDialog(this, "销售记录添加成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                        dispose();
                    } catch (SQLException ex) {
                        JOptionPane.showMessageDialog(this, "添加失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                        ex.printStackTrace();
                    }
                } catch (NumberFormatException ex) {
                    JOptionPane.showMessageDialog(this, "请输入有效的销售数量", "错误", JOptionPane.ERROR_MESSAGE);
                }
            }

            private Product getProductByName(String name) {
                try (Connection conn = getConnection();
                     PreparedStatement stmt = conn.prepareStatement(
                             "SELECT * FROM tb_product WHERE product_name = ?")) {

                    stmt.setString(1, name);
                    ResultSet rs = stmt.executeQuery();
                    if (rs.next()) {
                        return new Product(
                                rs.getInt("id"),
                                rs.getInt("group_id"),
                                null,
                                rs.getInt("provider_id"),
                                null,
                                rs.getString("product_name"),
                                rs.getDate("yield_date"),
                                rs.getString("product_factory"),
                                rs.getFloat("purchase_price"),
                                rs.getInt("stock"),
                                rs.getFloat("sale_price"),
                                rs.getInt("sale_count"),
                                rs.getDate("create_date")
                        );
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
                return null;
            }

            public boolean isSuccess() {
                return success;
            }
        }
    }

    // ========================== 供应商管理面板 ==========================
    // ========================== 供应商管理面板 ==========================
    class SupplierPanel extends JPanel {
        private JTable supplierTable;
        private SupplierTableModel tableModel;
        private JTextField phoneSearchField; // 新增联系电话查询字段

        public SupplierPanel() {
            setLayout(new BorderLayout());

            // 顶部工具栏
            JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

            // 在顶部工具栏中添加电话查询功能
            topPanel.add(new JLabel("联系电话:"));
            phoneSearchField = new JTextField(15);
            topPanel.add(phoneSearchField);

            JButton phoneSearchButton = new JButton("电话查询");
            phoneSearchButton.addActionListener(e -> searchSupplierByPhone());
            topPanel.add(phoneSearchButton);

            // 添加按钮
            JButton addButton = new JButton("添加供应商");
            addButton.addActionListener(e -> showAddSupplierDialog());
            topPanel.add(addButton);

            // 编辑按钮
            JButton editButton = new JButton("编辑供应商");
            editButton.addActionListener(e -> showEditSupplierDialog());
            topPanel.add(editButton);

            // 删除按钮
            JButton deleteButton = new JButton("删除供应商");
            deleteButton.addActionListener(e -> deleteSupplier());
            topPanel.add(deleteButton);

            // 刷新按钮
            JButton refreshButton = new JButton("刷新数据");
            refreshButton.addActionListener(e -> loadSuppliers());
            topPanel.add(refreshButton);

            add(topPanel, BorderLayout.NORTH);

            // 供应商表格
            tableModel = new SupplierTableModel();
            supplierTable = new JTable(tableModel);
            supplierTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            JScrollPane scrollPane = new JScrollPane(supplierTable);
            add(scrollPane, BorderLayout.CENTER);

            // 加载供应商数据
            loadSuppliers();
        }

        private void searchSupplierByPhone() {
            String phone = phoneSearchField.getText().trim();
            if (phone.isEmpty()) {
                loadSuppliers(); // 加载全部
                return;
            }

            tableModel.clear();
            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "SELECT * FROM tb_provider WHERE contact_phone LIKE ?")) {

                stmt.setString(1, "%" + phone + "%");
                ResultSet rs = stmt.executeQuery();

                while (rs.next()) {
                    Provider provider = new Provider(
                            rs.getInt("id"),
                            rs.getString("provider_name"),
                            rs.getString("provider_contact"),
                            rs.getString("contact_phone"),
                            rs.getString("provider_address")
                    );
                    tableModel.addProvider(provider);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void loadSuppliers() {
            tableModel.clear();
            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT * FROM tb_provider")) {

                while (rs.next()) {
                    Provider provider = new Provider(
                            rs.getInt("id"),
                            rs.getString("provider_name"),
                            rs.getString("provider_contact"),
                            rs.getString("contact_phone"),
                            rs.getString("provider_address")
                    );
                    tableModel.addProvider(provider);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void showAddSupplierDialog() {
            AddEditSupplierDialog dialog = new AddEditSupplierDialog(null, "添加供应商");
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadSuppliers();
            }
        }

        private void showEditSupplierDialog() {
            int selectedRow = supplierTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请先选择要编辑的供应商", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            Provider provider = tableModel.getProviderAt(selectedRow);
            AddEditSupplierDialog dialog = new AddEditSupplierDialog(provider, "编辑供应商");
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadSuppliers();
            }
        }

        private void deleteSupplier() {
            int selectedRow = supplierTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请先选择要删除的供应商", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            int confirm = JOptionPane.showConfirmDialog(this,
                    "确定要删除这个供应商吗？", "确认删除", JOptionPane.YES_NO_OPTION);
            if (confirm != JOptionPane.YES_OPTION) {
                return;
            }

            Provider provider = tableModel.getProviderAt(selectedRow);
            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "DELETE FROM tb_provider WHERE id = ?")) {

                stmt.setInt(1, provider.getId());
                int rows = stmt.executeUpdate();
                if (rows > 0) {
                    JOptionPane.showMessageDialog(this, "供应商删除成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                    loadSuppliers();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(this, "删除失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }

        class SupplierTableModel extends AbstractTableModel {
            private String[] columnNames = {
                    "ID", "供应商名称", "联系人", "联系电话", "地址"
            };

            private List<Provider> providers = new ArrayList<>();

            public void addProvider(Provider provider) {
                providers.add(provider);
            }

            public void clear() {
                providers.clear();
            }

            public Provider getProviderAt(int row) {
                return providers.get(row);
            }

            @Override
            public int getRowCount() {
                return providers.size();
            }

            @Override
            public int getColumnCount() {
                return columnNames.length;
            }

            @Override
            public String getColumnName(int column) {
                return columnNames[column];
            }

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                Provider provider = providers.get(rowIndex);
                switch (columnIndex) {
                    case 0: return provider.getId();
                    case 1: return provider.getName();
                    case 2: return provider.getContact();
                    case 3: return provider.getPhone();
                    case 4: return provider.getAddress();
                    default: return null;
                }
            }
        }

        class AddEditSupplierDialog extends JDialog {
            private boolean success = false;
            private JTextField nameField, contactField, phoneField, addressField;

            public AddEditSupplierDialog(Provider provider, String title) {
                setTitle(title);
                setSize(500, 300);
                setModal(true);
                setLocationRelativeTo(SupplierPanel.this);

                JPanel panel = new JPanel(new GridLayout(5, 2, 10, 10));
                panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

                // 供应商名称
                panel.add(new JLabel("供应商名称:"));
                nameField = new JTextField();
                panel.add(nameField);

                // 联系人
                panel.add(new JLabel("联系人:"));
                contactField = new JTextField();
                panel.add(contactField);

                // 联系电话
                panel.add(new JLabel("联系电话:"));
                phoneField = new JTextField();
                panel.add(phoneField);

                // 地址
                panel.add(new JLabel("地址:"));
                addressField = new JTextField();
                panel.add(addressField);

                // 按钮面板
                JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
                JButton saveButton = new JButton("保存");
                saveButton.addActionListener(e -> saveSupplier(provider));
                buttonPanel.add(saveButton);

                JButton cancelButton = new JButton("取消");
                cancelButton.addActionListener(e -> dispose());
                buttonPanel.add(cancelButton);

                // 设置初始值（如果是编辑）
                if (provider != null) {
                    nameField.setText(provider.getName());
                    contactField.setText(provider.getContact());
                    phoneField.setText(provider.getPhone());
                    addressField.setText(provider.getAddress());
                }

                add(panel, BorderLayout.CENTER);
                add(buttonPanel, BorderLayout.SOUTH);
            }

            private void saveSupplier(Provider originalProvider) {
                try {
                    String name = nameField.getText();
                    String contact = contactField.getText();
                    String phone = phoneField.getText();
                    String address = addressField.getText();

                    if (name.isEmpty() || contact.isEmpty() || phone.isEmpty() || address.isEmpty()) {
                        JOptionPane.showMessageDialog(this, "请填写所有字段", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    if (originalProvider == null) {
                        // 添加新供应商
                        try (Connection conn = getConnection();
                             PreparedStatement stmt = conn.prepareStatement(
                                     "INSERT INTO tb_provider (provider_name, provider_contact, contact_phone, provider_address) " +
                                             "VALUES (?, ?, ?, ?)")) {

                            stmt.setString(1, name);
                            stmt.setString(2, contact);
                            stmt.setString(3, phone);
                            stmt.setString(4, address);

                            int rows = stmt.executeUpdate();
                            if (rows > 0) {
                                success = true;
                                JOptionPane.showMessageDialog(this, "供应商添加成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                                dispose();
                            }
                        }
                    } else {
                        // 更新现有供应商
                        try (Connection conn = getConnection();
                             PreparedStatement stmt = conn.prepareStatement(
                                     "UPDATE tb_provider SET provider_name = ?, provider_contact = ?, " +
                                             "contact_phone = ?, provider_address = ? WHERE id = ?")) {

                            stmt.setString(1, name);
                            stmt.setString(2, contact);
                            stmt.setString(3, phone);
                            stmt.setString(4, address);
                            stmt.setInt(5, originalProvider.getId());

                            int rows = stmt.executeUpdate();
                            if (rows > 0) {
                                success = true;
                                JOptionPane.showMessageDialog(this, "供应商更新成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                                dispose();
                            }
                        }
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(this, "保存失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                }
            }

            public boolean isSuccess() {
                return success;
            }
        }
    }

    // ========================== 用户管理面板 ==========================
    class UserPanel extends JPanel {
        private JTable userTable;
        private UserTableModel tableModel;

        public UserPanel() {
            setLayout(new BorderLayout());

            // 顶部工具栏
            JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

            // 添加按钮
            JButton addButton = new JButton("添加用户");
            addButton.addActionListener(e -> showAddUserDialog());
            topPanel.add(addButton);

            // 编辑按钮
            JButton editButton = new JButton("编辑用户");
            editButton.addActionListener(e -> showEditUserDialog());
            topPanel.add(editButton);

            // 删除按钮
            JButton deleteButton = new JButton("删除用户");
            deleteButton.addActionListener(e -> deleteUser());
            topPanel.add(deleteButton);

            // 刷新按钮
            JButton refreshButton = new JButton("刷新数据");
            refreshButton.addActionListener(e -> loadUsers());
            topPanel.add(refreshButton);

            add(topPanel, BorderLayout.NORTH);

            // 用户表格
            tableModel = new UserTableModel();
            userTable = new JTable(tableModel);
            userTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
            JScrollPane scrollPane = new JScrollPane(userTable);
            add(scrollPane, BorderLayout.CENTER);

            // 加载用户数据
            loadUsers();
        }

        private void loadUsers() {
            tableModel.clear();
            try (Connection conn = getConnection();
                 Statement stmt = conn.createStatement();
                 ResultSet rs = stmt.executeQuery("SELECT * FROM tb_user")) {

                while (rs.next()) {
                    User user = new User(
                            rs.getInt("id"),
                            rs.getString("username"),
                            rs.getString("password"),
                            rs.getString("role")
                    );
                    tableModel.addUser(user);
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            tableModel.fireTableDataChanged();
        }

        private void showAddUserDialog() {
            AddEditUserDialog dialog = new AddEditUserDialog(null, "添加用户");
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadUsers();
            }
        }

        private void showEditUserDialog() {
            int selectedRow = userTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请先选择要编辑的用户", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            User user = tableModel.getUserAt(selectedRow);
            AddEditUserDialog dialog = new AddEditUserDialog(user, "编辑用户");
            dialog.setVisible(true);
            if (dialog.isSuccess()) {
                loadUsers();
            }
        }

        private void deleteUser() {
            int selectedRow = userTable.getSelectedRow();
            if (selectedRow == -1) {
                JOptionPane.showMessageDialog(this, "请先选择要删除的用户", "提示", JOptionPane.WARNING_MESSAGE);
                return;
            }

            User user = tableModel.getUserAt(selectedRow);

            // 不能删除当前登录用户
            if (user.getUsername().equals(currentUser)) {
                JOptionPane.showMessageDialog(this, "不能删除当前登录用户", "错误", JOptionPane.ERROR_MESSAGE);
                return;
            }

            int confirm = JOptionPane.showConfirmDialog(this,
                    "确定要删除这个用户吗？", "确认删除", JOptionPane.YES_NO_OPTION);
            if (confirm != JOptionPane.YES_OPTION) {
                return;
            }

            try (Connection conn = getConnection();
                 PreparedStatement stmt = conn.prepareStatement(
                         "DELETE FROM tb_user WHERE id = ?")) {

                stmt.setInt(1, user.getId());
                int rows = stmt.executeUpdate();
                if (rows > 0) {
                    JOptionPane.showMessageDialog(this, "用户删除成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                    loadUsers();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
                JOptionPane.showMessageDialog(this, "删除失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
            }
        }

        class UserTableModel extends AbstractTableModel {
            private String[] columnNames = {
                    "ID", "用户名", "密码", "角色"
            };

            private List<User> users = new ArrayList<>();

            public void addUser(User user) {
                users.add(user);
            }

            public void clear() {
                users.clear();
            }

            public User getUserAt(int row) {
                return users.get(row);
            }

            @Override
            public int getRowCount() {
                return users.size();
            }

            @Override
            public int getColumnCount() {
                return columnNames.length;
            }

            @Override
            public String getColumnName(int column) {
                return columnNames[column];
            }

            @Override
            public Object getValueAt(int rowIndex, int columnIndex) {
                User user = users.get(rowIndex);
                switch (columnIndex) {
                    case 0: return user.getId();
                    case 1: return user.getUsername();
                    case 2: return "******"; // 不显示真实密码
                    case 3: return user.getRole();
                    default: return null;
                }
            }
        }

        class AddEditUserDialog extends JDialog {
            private boolean success = false;
            private JTextField usernameField;
            private JPasswordField passwordField;
            private JComboBox<String> roleCombo;

            public AddEditUserDialog(User user, String title) {
                setTitle(title);
                setSize(400, 250);
                setModal(true);
                setLocationRelativeTo(UserPanel.this);

                JPanel panel = new JPanel(new GridLayout(5, 2, 10, 10));
                panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

                // 用户名
                panel.add(new JLabel("用户名:"));
                usernameField = new JTextField();
                panel.add(usernameField);

                // 密码
                panel.add(new JLabel("密码:"));
                passwordField = new JPasswordField();
                panel.add(passwordField);

                // 角色
                panel.add(new JLabel("角色:"));
                roleCombo = new JComboBox<>(new String[]{"admin", "user"});
                panel.add(roleCombo);

                // 按钮面板
                JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
                JButton saveButton = new JButton("保存");
                saveButton.addActionListener(e -> saveUser(user));
                buttonPanel.add(saveButton);

                JButton cancelButton = new JButton("取消");
                cancelButton.addActionListener(e -> dispose());
                buttonPanel.add(cancelButton);

                // 设置初始值（如果是编辑）
                if (user != null) {
                    usernameField.setText(user.getUsername());
                    roleCombo.setSelectedItem(user.getRole());
                }

                add(panel, BorderLayout.CENTER);
                add(buttonPanel, BorderLayout.SOUTH);
            }

            private void saveUser(User originalUser) {
                try {
                    String username = usernameField.getText();
                    String password = new String(passwordField.getPassword());
                    String role = (String) roleCombo.getSelectedItem();

                    if (username.isEmpty() || password.isEmpty()) {
                        JOptionPane.showMessageDialog(this, "请填写所有字段", "错误", JOptionPane.ERROR_MESSAGE);
                        return;
                    }

                    if (originalUser == null) {
                        // 检查用户名是否已存在
                        if (isUsernameExists(username)) {
                            JOptionPane.showMessageDialog(this, "用户名已存在", "错误", JOptionPane.ERROR_MESSAGE);
                            return;
                        }

                        // 添加新用户
                        try (Connection conn = getConnection();
                             PreparedStatement stmt = conn.prepareStatement(
                                     "INSERT INTO tb_user (username, password, role) VALUES (?, ?, ?)")) {

                            stmt.setString(1, username);
                            stmt.setString(2, password);
                            stmt.setString(3, role);

                            int rows = stmt.executeUpdate();
                            if (rows > 0) {
                                success = true;
                                JOptionPane.showMessageDialog(this, "用户添加成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                                dispose();
                            }
                        }
                    } else {
                        // 更新现有用户
                        try (Connection conn = getConnection();
                             PreparedStatement stmt = conn.prepareStatement(
                                     "UPDATE tb_user SET username = ?, password = ?, role = ? WHERE id = ?")) {

                            stmt.setString(1, username);
                            stmt.setString(2, password);
                            stmt.setString(3, role);
                            stmt.setInt(4, originalUser.getId());

                            int rows = stmt.executeUpdate();
                            if (rows > 0) {
                                success = true;
                                JOptionPane.showMessageDialog(this, "用户更新成功", "成功", JOptionPane.INFORMATION_MESSAGE);
                                dispose();
                            }
                        }
                    }
                } catch (SQLException ex) {
                    ex.printStackTrace();
                    JOptionPane.showMessageDialog(this, "保存失败: " + ex.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
                }
            }

            private boolean isUsernameExists(String username) throws SQLException {
                try (Connection conn = getConnection();
                     PreparedStatement stmt = conn.prepareStatement(
                             "SELECT COUNT(*) FROM tb_user WHERE username = ?")) {

                    stmt.setString(1, username);
                    ResultSet rs = stmt.executeQuery();
                    if (rs.next()) {
                        return rs.getInt(1) > 0;
                    }
                }
                return false;
            }

            public boolean isSuccess() {
                return success;
            }
        }
    }



    // ========================== 数据模型类 ==========================
    class Product {
        private int id;
        private int groupId;
        private String groupName;
        private int providerId;
        private String providerName;
        private String name;
        private Date yieldDate;
        private String factory;
        private float purchasePrice;
        private int stock;
        private float salePrice;
        private int saleCount;
        private Date createDate;

        public Product(int id, int groupId, String groupName, int providerId, String providerName,
                       String name, Date yieldDate, String factory, float purchasePrice,
                       int stock, float salePrice, int saleCount, Date createDate) {
            this.id = id;
            this.groupId = groupId;
            this.groupName = groupName;
            this.providerId = providerId;
            this.providerName = providerName;
            this.name = name;
            this.yieldDate = yieldDate;
            this.factory = factory;
            this.purchasePrice = purchasePrice;
            this.stock = stock;
            this.salePrice = salePrice;
            this.saleCount = saleCount;
            this.createDate = createDate;
        }

        // Getters
        public int getId() { return id; }
        public int getGroupId() { return groupId; }
        public String getGroupName() { return groupName; }
        public int getProviderId() { return providerId; }
        public String getProviderName() { return providerName; }
        public String getName() { return name; }
        public Date getYieldDate() { return yieldDate; }
        public String getFactory() { return factory; }
        public float getPurchasePrice() { return purchasePrice; }
        public int getStock() { return stock; }
        public float getSalePrice() { return salePrice; }
        public int getSaleCount() { return saleCount; }
        public Date getCreateDate() { return createDate; }
    }

    class Sale {
        private int saleId;
        private int productId;
        private String productName;
        private int groupId;
        private String groupName;
        private float purchasePrice;
        private float salePrice;
        private int saleCount;
        private float saleVolume;
        private float netProfit;
        private Date generateTime;

        public Sale(int saleId, int productId, String productName, int groupId, String groupName,
                    float purchasePrice, float salePrice, int saleCount,
                    float saleVolume, float netProfit, Date generateTime) {
            this.saleId = saleId;
            this.productId = productId;
            this.productName = productName;
            this.groupId = groupId;
            this.groupName = groupName;
            this.purchasePrice = purchasePrice;
            this.salePrice = salePrice;
            this.saleCount = saleCount;
            this.saleVolume = saleVolume;
            this.netProfit = netProfit;
            this.generateTime = generateTime;
        }

        // Getters
        public int getSaleId() { return saleId; }
        public int getProductId() { return productId; }
        public String getProductName() { return productName; }
        public int getGroupId() { return groupId; }
        public String getGroupName() { return groupName; }
        public float getPurchasePrice() { return purchasePrice; }
        public float getSalePrice() { return salePrice; }
        public int getSaleCount() { return saleCount; }
        public float getSaleVolume() { return saleVolume; }
        public float getNetProfit() { return netProfit; }
        public Date getGenerateTime() { return generateTime; }
    }

    class Provider {
        private int id;
        private String name;
        private String contact;
        private String phone;
        private String address;

        public Provider(int id, String name, String contact, String phone, String address) {
            this.id = id;
            this.name = name;
            this.contact = contact;
            this.phone = phone;
            this.address = address;
        }

        // Getters
        public int getId() { return id; }
        public String getName() { return name; }
        public String getContact() { return contact; }
        public String getPhone() { return phone; }
        public String getAddress() { return address; }
    }

    class User {
        private int id;
        private String username;
        private String password;
        private String role;

        public User(int id, String username, String password, String role) {
            this.id = id;
            this.username = username;
            this.password = password;
            this.role = role;
        }

        // Getters
        public int getId() { return id; }
        public String getUsername() { return username; }
        public String getPassword() { return password; }
        public String getRole() { return role; }
    }
}